package com.ckjava.aop;

import com.ckjava.aop.annotation.MultiDataSource;
import com.ckjava.config.MultiDataSourceHolder;
import com.ckjava.entity.DbEnum;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 通过 aop 来读取注解的配置，并在方法前后进行数据库的切换
 */
@Aspect
@Component
@Order(1)
public class MultiDataSourceAspect {

    @Pointcut("@annotation(com.ckjava.aop.annotation.MultiDataSource)")
    public void dataSourcePointCut() {
    }

    /**
     * 在方法执行前设置数据库 key
     *
     * @param point
     */
    @Before("dataSourcePointCut()")
    public void before(JoinPoint point) {
        MethodSignature signature = (MethodSignature) point.getSignature();
        Method method = signature.getMethod();

        // 在含有 MultiDataSource 注解的方法执行前，设置线程的数据库源变量
        MultiDataSource dataSource = method.getAnnotation(MultiDataSource.class);
        if (dataSource == null) {
            MultiDataSourceHolder.setDataSource(DbEnum.user);
        } else {
            MultiDataSourceHolder.setDataSource(dataSource.value());
        }
    }

    /**
     * 在方法执行后移除 数据库 key
     */
    @After("dataSourcePointCut()")
    public void after() {
        // 移除线程本地数据库源变量
        MultiDataSourceHolder.clearDataSource();
    }
}
